home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgramD2.iso
/
Borland
/
Borland C++ V5.02
/
START16.PAK
/
C0W.ASM
< prev
next >
Wrap
Assembly Source File
|
1997-05-06
|
13KB
|
482 lines
;[]------------------------------------------------------------[]
;| C0W.ASM -- Start Up Code For Windows |
;[]------------------------------------------------------------[]
;
; C/C++ Run Time Library - Version 8.0
;
; Copyright (c) 1991, 1997 by Borland International
; All Rights Reserved.
;
; $Revision: 8.2 $
locals
.286
__C0__ = 1
include RULES.ASI
ASSUME CS:_TEXT, DS:DGROUP
public __acrtused ;satisfy MS for now
__acrtused equ 0
IFNDEF __DPMI16__
public __WINMAINCALL ; used internally
ENDIF
public __INITAPPCALLED ; used internally
IFNDEF __DPMI16__
extrn WINMAIN:DIST
ENDIF
extrn INITAPP:far
extrn INITTASK:far
extrn FATALEXIT:far
extrn WAITEVENT:far
extrn LOCKSEGMENT:far
extrn UNLOCKSEGMENT:far
extrn GETWINFLAGS:far
IFDEF __LARGE__
extrn MESSAGEBOX:far
ENDIF
IFDEF __DPMI16__
extrn _main:DIST
extrn _OkToInitWindowsRTL:DIST
extrn __abort:DIST
ENDIF
extrn _exit:DIST
extrn __exit:DIST
extrn __exitbuf:DIST
extrn __exitfopen:DIST
extrn __exitopen:DIST
extrn __setupio:near ;required!
extrn __ExceptInit:DIST
public __DestructorCount ;Offset to global destructor count
__DestructorCount EQU 10H
public __Exception_list ;Offset to global exception list
__Exception_list EQU 14H
NULL segment
db 16 dup (0) ;Windows
db 4 dup (0) ;destructor count
db 2 dup (0) ;exception list
db 4 dup (0) ;exception vptr
db 6 dup (0) ;reserved
db 2 dup (0) ;VBX control jump vector
;MUST be at SS:20h
db 2 dup (0) ;reserved
ends
_CVTSEG segment
public __RealCvtVector
__RealCvtVector label word
ends
_SCNSEG segment
public __ScanTodVector
__ScanTodVector label word
ends
_FPSEG segment
public __FPVector
__FPVector dd 0
ends
_DATA segment
public _errno
_errno dw 0
public __protected
__protected dw 0
public __8086
__8086 dw 0
public __8087
__8087 dw 0
public __psp
__psp dw 0
public __hInstance
__hInstance dw 0
public __hPrev
__hPrev dw 0
public __pszCmdline
__pszCmdline dw 0
public __cmdShow
__cmdShow dw 0
public __version
__version label word
public __osversion
__osversion label word
public __osmajor
__osmajor db 0
public __osminor
__osminor db 0
public __osmode ;Used for OS/2 protected mode by MS,
__osmode db 0 ; currently set to 0 under Windows
public __WinAllocFlag ;Used by malloc to get additional flags
__WinAllocFlag dw 0 ; to pass to GlobalAlloc (for DLL use)
public __LockWIN87EM ;Used do lock down WIN87EM to avoid
__LockWIN87EM dw 1 ; DLL unload ordering problem
public __abend
__abend dw 0 ;Signals abnormal end, don't run destructors etc.
IFDEF __DPMI16__
extrn __C0environ:dword
extrn __C0argv:dword
extrn __C0argc:word
ENDIF
CopyRight db 'Borland C++ - Copyright 1995 Borland Intl.',0
IFDEF __LARGE__
CGFailMessage db 'CodeGuard cannot be run with multiple processes',0
CGMessageTitle db 'CodeGuard Message',0
CGFail dw 0
ENDIF
IFDEF __DPMI16__
DPMI16Error_s db 'This DPMI16 application was linked incorrectly and'
db ' will fail.',10,13,'$'
ENDIF
ends
_TEXT segment
Main proc near
IFDEF __LARGE__
jmp @@Start
db 'CGINITCB' ; signature
dw offset CGFail ; offset in DGROUP of status word
ENDIF
@@Start:
;Windows initialization. Sets up registers and stack.
IFDEF __DPMI16__
mov ax, seg DGROUP
mov ds, ax
ENDIF
push bx cx es
xor ax,ax
push ax
call __ExceptInit
pop ax
pop es cx bx
;INITTASK returns:
; 'Failure:
; AX = zero if it failed
; Success:
; AX = 1
; CX = stack limit
; DX = cmdShow parameter to CreateWindow
; ES:BX = -> DOS format command line (ES = PSP address)
; SI = hPrevinstance
; DI = hinstance
call INITTASK
or ax,ax
jnz @@OK
jmp @@Fail
@@OK: mov word ptr ss:[__Exception_list], -1
mov __psp,es
mov word ptr __pszCmdline,bx
mov __hPrev,si
mov __hInstance,di
mov __cmdShow,dx
IF LDATA EQ false
mov ax,-1
push ax
call LOCKSEGMENT
ENDIF
;Clear _BSS, uninitialized data area
IFNDEF __HUGE__
xor ax, ax
push ds
pop es
mov di,offset DGROUP:BeginBSS
mov cx,offset DGROUP:EndBSS
sub cx,di
cld
rep
stosb
ENDIF
;Init the Windows App
xor ax,ax
push ax
call WAITEVENT
push __hInstance
call INITAPP
__INITAPPCALLED:
IFDEF __LARGE__
;Check whether CodeGuard detected multiple clients
cmp CGFail,0
je @@TestInit
;If so then display message and fail initializaion
pusha
call MESSAGEBOX pascal, 0, ds offset CGFailMessage, ds offset CGMessageTitle, 1010h ; MB_ICONSTOP | MB_SYSTEMMODAL
popa
xor ax,ax
ENDIF
;Test whether INITAPP suceeded
@@TestInit: or ax,ax
jnz @@InitOK
jmp @@Fail
@@InitOK:
;Determine DOS version
mov ah, 30h
int 21h
mov __version, ax ; save minor and major revision
;Determine whether we are in protected mode
call GETWINFLAGS
test ax,1 ; WF_PMODE = 1
jz @@realmode ; Note: GETWINFLAGS returns a long,
; so if WF_PMODE changed it could be
; in the high word.
mov __protected, 8 ; Eight is for convenience.
@@realmode:
;Test for 8086/8087 presence
test ax,0400h ; WF_8087 = 0x0400
jz @@no8087
mov __8087, 1
@@no8087:
and ax,08h+04h+02h ; WF_CPU486|WF_CPU386|WF_CPU286
shr ax,1 ; Convert to 4 or 2 or 1 or 0
test ax,0004h ; Have 4, 486 done
jnz @@NoAdjust
or ax,ax ; Have 0, 8086 done
jz @@NoAdjust
inc ax ; Have 2 or 1, need 3 or 2
@@NoAdjust:
mov __8086,ax ; Set CPU Type
IFDEF __DPMI16__
;
; Here we attempt to prevent an early death caused by linking
; the libs in the wrong order
;
call _OkToInitWindowsRTL
or ax, ax
jnz DPMI16Error
ENDIF
;Call our initialization functions, including C++ static constructors.
mov ax,ds
mov es,ax
mov si,offset DGROUP:InitStart ;si = start of table
mov di,offset DGROUP:InitEnd ;di = end of table
call Initialize
IFDEF __DPMI16__
;Set up and call _main for DPMI16 application
push word ptr [__C0environ+2]
push word ptr [__C0environ]
push word ptr [__C0argv+2]
push word ptr [__C0argv]
push [__C0argc]
call _main
ELSE
;Set up and call WinMain for Windows application
push __hInstance
push __hPrev
push __psp
push word ptr __pszCmdline
push __cmdShow
__WINMAINCALL: call WINMAIN
ENDIF
push ax ; Push return value
cmp __abend, 0
jne @@abnormalexit
call _exit ; Normal exit
@@abnormalexit: call __exit ; Abnormal exit, don't call destructors etc.
IFDEF __DPMI16__
DPMI16Error:
mov ah, 9
mov dx, offset DPMI16Error_s
int 21h
call __abort
ENDIF
;---------------------------------------------------------------------------
; _cleanup() call all #pragma exit cleanup routines.
; _checknull() check for null pointer zapping copyright message
; _terminate(int) exit program with error code
; _restorezero() restore interrupt vectors
;
; These functions are called by exit(), _exit(), _cexit(),
; and _c_exit().
;---------------------------------------------------------------------------
; Call cleanup routines
__cleanup PROC DIST
PUBLIC __cleanup
mov ax,ds
mov es,ax
push si
push di
mov si,offset DGROUP:ExitStart
mov di,offset DGROUP:ExitEnd
call Cleanup
pop di
pop si
ret
__cleanup ENDP
; Check for null pointers before exit. NO-OP on Windows.
__checknull PROC DIST
PUBLIC __checknull
ret
__checknull ENDP
; Restore grabbed interrupt vectors. NO-OP on Windows.
__restorezero PROC DIST
PUBLIC __restorezero
ret
__restorezero ENDP
; Exit to DOS
__terminate PROC DIST
PUBLIC __terminate
IF LDATA EQ false
mov ax,-1
push ax
call UNLOCKSEGMENT
ENDIF
mov bp,sp
mov al,[bp+cPtrSize]
mov ah,4ch ;exit
int 21h
__terminate ENDP
@@Fail: mov al,0ffh
push ax
call _exit
mov ah,4ch ;exit
int 21h
endp
; Return default data segment in AX
__GetDGROUP PROC FAR
PUBLIC __GetDGROUP
mov ax, ss
ret
endp
;------------------------------------------------------------------
; Loop through a startup/exit (SE) table,
; calling functions in order of priority.
; ES:SI is assumed to point to the beginning of the SE table
; ES:DI is assumed to point to the end of the SE table
; First 64 priorities are reserved by Borland
;------------------------------------------------------------------
PNEAR EQU 0
PFAR EQU 1
NOTUSED EQU 0ffh
SE STRUC
calltype db ? ; 0=near,1=far,ff=not used
priority db ? ; 0=highest,ff=lowest
addrlow dw ?
addrhigh dw ?
SE ENDS
Initialize proc near
@@Start: mov ax,100h ;start with lowest priority
mov dx,di ;set sentinel to end of table
mov bx,si ;bx = start of table
@@TopOfTable: cmp bx,di ;and the end of the table?
je @@EndOfTable ;yes, exit the loop
cmp es:[bx.calltype],NOTUSED;check the call type
je @@Next
mov cl, es:[bx.priority] ;move priority to CX
xor ch, ch
cmp cx,ax ;check the priority
jae @@Next ;too high? skip
mov ax,cx ;keep priority
mov dx,bx ;keep index in dx
@@Next: add bx,SIZE SE ;bx = next item in table
jmp @@TopOfTable
@@EndOfTable: cmp dx,di ;did we exhaust the table?
je @@Done ;yes, quit
mov bx,dx ;bx = highest priority item
cmp es:[bx.calltype],PNEAR ;is it near or far?
mov es:[bx.calltype],NOTUSED;wipe the call type
push es ;save es
je @@NearCall
@@FarCall: call DWORD PTR es:[bx.addrlow]
pop es ;restore es
jmp short @@Start
@@NearCall: call WORD PTR es:[bx.addrlow]
pop es ;restore es
jmp short @@Start
@@Done: ret
endp
Cleanup proc near
@@Start: mov ah,0 ;start with highest priority
mov dx,di ;set sentinel to end of table
mov bx,si ;bx = start of table
@@TopOfTable: cmp bx,di ;and the end of the table?
je @@EndOfTable ;yes, exit the loop
cmp es:[bx.calltype],NOTUSED;check the call type
je @@Next
cmp es:[bx.priority],ah ;check the priority
jb @@Next ;too low? skip
mov ah,es:[bx.priority] ;keep priority
mov dx,bx ;keep index in dx
@@Next: add bx,SIZE SE ;bx = next item in table
jmp @@TopOfTable
@@EndOfTable: cmp dx,di ;did we exhaust the table?
je @@Done ;yes, quit
mov bx,dx ;bx = highest priority item
cmp es:[bx.calltype],PNEAR ;is it near or far?
mov es:[bx.calltype],NOTUSED;wipe the call type
push es ;save es
je @@NearCall
@@FarCall: call DWORD PTR es:[bx.addrlow]
pop es ;restore es
jmp short @@Start
@@NearCall: call WORD PTR es:[bx.addrlow]
pop es ;restore es
jmp short @@Start
@@Done: ret
endp
ends
end Main